import { _decorator, Node, Sprite, UITransform } from 'cc';
import { IBullte, IVec2 } from '../../Common/Interface/State';
import { EntityManager } from '../../Base/EntityManager';
import { BulletStateMachine } from './BulletStateMachine';
import { createUINode } from '../../Utils';
import { ObjectPoolManager } from '../../Runtime/ObjectPoolManager';
import DataManager from '../../Runtime/DataManager';
import { EntityTypeEnum, G, GBulletLiveTime, StateTypeEnum, vecToAngel } from '../../Common';
import { addExplosion, addLabel } from '../../Runtime/MainManager';
const { ccclass, property } = _decorator;

@ccclass('BulletManager')
export class BulletManager extends EntityManager {
    body: Node
    id: number
    /** 已存在时间 */
    aliveTime: number = 0

    init(bullet: IBullte) {

        this.type = bullet.type

        this.body = createUINode('body')
        this.body.parent = this.node
        const sprite = this.body.addComponent(Sprite)
        sprite.trim = false
        sprite.sizeMode = Sprite.SizeMode.CUSTOM

        const uiTransform = this.body.getComponent(UITransform)
        uiTransform.setContentSize(G.BulletEntitySize.w, G.BulletEntitySize.h)

        this.fsm = this.addComponent(BulletStateMachine)
        this.fsm.init(this)
    }

    reset(bullet: IBullte) {
        this.aliveTime = 0
        const {
            position: { x, y },
            type,
            id
        } = bullet

        this.node.setPosition(x, y)

        this.type = type
        this.id = id
    }

    bulletDie(bullet: IBullte, { x, y }: IVec2, damage: number, state: StateTypeEnum
    ) {
        ObjectPoolManager.Ins.poolFree(this)
        DataManager.Ins.bulletMap.delete(this.id)
        DataManager.Ins.enemyBulletMap.delete(this.id)

        if (bullet.aliveTime < GBulletLiveTime[bullet.type]) {
            addExplosion(bullet.position)
            if (state === StateTypeEnum.dead) {
                addLabel(damage, EntityTypeEnum.fontYellow, { x, y })
            } else if (state === StateTypeEnum.deadCrit) {
                addLabel(Math.floor(damage * bullet.critRate), EntityTypeEnum.fontRed, { x, y })
            }
        }
    }

    render(bullet: IBullte, dt: number) {
        this.aliveTime += dt
        const {
            position: { x, y },
            direction,
            state,
            damage,
            critRate
        } = bullet

        this.state = state
        let angel = vecToAngel(direction.x, direction.y)
        this.node.setRotationFromEuler(0, 0, angel)
        this.node.setScale(1, Math.abs(angel) < 90 ? 1 : -1)

        this.node.setPosition(x, y)
        if (state === StateTypeEnum.dead || state === StateTypeEnum.deadCrit) {
            this.bulletDie(bullet, { x, y }, damage, state)
        } else if (state === StateTypeEnum.hit) {
            addExplosion(bullet.position)
            addLabel(damage, EntityTypeEnum.fontYellow, { x, y })
        } else if (state === StateTypeEnum.hitCrit) {
            addExplosion(bullet.position)
            addLabel(Math.floor(damage * critRate), EntityTypeEnum.fontRed, { x, y })
        }
    }

}


